#include "ClientCmdRecive.h"
#include "Utility.h"


IMPL_LOGGER(ClientCmdRecive,logger);

ClientCmdRecive::ClientCmdRecive()
{
}

ClientCmdRecive::~ClientCmdRecive()
{
}

bool ClientCmdRecive::init()
{

    if(!init_event_base())
    {
        LOG4CPLUS_ERROR(logger,"init event base fail");
        return false;
    }
    
    return true;
}

void ClientCmdRecive::start_thread(ClientCmdRecive &arg)
{
    LOG4CPLUS_DEBUG(logger,"start client cmd recive");

    if(!arg.init())
    {
        LOG4CPLUS_ERROR(logger,"init event base fail");
        abort();
    }
    
    CLIENTSOCKET client_socket;

    while(g_GlobalDataQueue_Mgr::instance().m_client_socket_queue->pop_one(client_socket))
    {
        if(!client_socket)
        {
            LOG4CPLUS_DEBUG(logger,"get a NULL client");
            continue;
        }

        LOG4CPLUS_DEBUG(logger,"get a client");

        CLIENTCMD tp(new ClientCmd());

        if(tp==NULL)
        {
            LOG4CPLUS_DEBUG(logger,"create a client cmd error");
            continue;
        }

        tp->m_client_socket = client_socket;

        if(!arg.put_client_in_base(tp))
        {
            LOG4CPLUS_DEBUG(logger,"put clent into event fail");
            continue;
        }

        LOG4CPLUS_DEBUG(logger,"put client into event succ");
        
        if(!g_GlobalDataQueue_Mgr::instance().m_client_cmd_queue->push(tp))
        {
            LOG4CPLUS_DEBUG(logger,"put client cmd into gloable queue faild ,we will lost this cmd");
        }
        
    }
    
    LOG4CPLUS_DEBUG(logger,"end client cmd recive")
}

void ClientCmdRecive::client_read_callback(evutil_socket_t fd,short what,void *arg)
{
    LOG4CPLUS_DEBUG(logger,"DEBUG CLIENT READ CALLBACK");

    ClientCmd   *ptr = (ClientCmd*) arg;
    
    char buff[1024];
    
    if(what&EV_READ)
    {
        LOG4CPLUS_DEBUG(logger,"READ EVENT HAPPEN");

        int len =0;
        do
        {
            len = read(fd,buff,1024);
            LOG4CPLUS_DEBUG(logger,"recv: "<<buff);
        }while(len>0);

        if(ptr&&(ptr->m_client_socket)&&(ptr->m_client_socket->m_client_evnt))
        {
             LOG4CPLUS_DEBUG(logger,"re put input socket event into event");
             event_del(ptr->m_client_socket->m_client_evnt);
             event_free(ptr->m_client_socket->m_client_evnt);
        }
        
    }
}

bool ClientCmdRecive::init_event_base()
{

    LOG4CPLUS_DEBUG(logger,"init event base");

    m_event_base = event_base_new();

    if(m_event_base==NULL)
    {

        LOG4CPLUS_ERROR(logger,"create event base fail");
        
        return false;
        
    }

    return true;
}


bool ClientCmdRecive::put_client_in_base(CLIENTCMD &client_cmd)
{
    LOG4CPLUS_DEBUG(logger,"start put client in base");
    
    if(Utility::set_linger(client_cmd->m_client_socket->m_client_fd)!=0)
    {
        LOG4CPLUS_ERROR(logger,"set client socket linger error: "<<strerror(errno));
        
        return false;
    }

    if(client_cmd->m_client_socket->m_client_fd<=0)
    {
        LOG4CPLUS_DEBUG(logger,"client socket error");
        return false;
    }

    LOG4CPLUS_DEBUG(logger,"client socket fd: "<<client_cmd->m_client_socket->m_client_fd);
    
    client_cmd->m_client_socket->m_client_evnt = 
    event_new(m_event_base,client_cmd->m_client_socket->m_client_fd,EV_READ,client_read_callback,client_cmd.get());

    if(client_cmd->m_client_socket->m_client_evnt==NULL)
    {
        LOG4CPLUS_ERROR(logger,"create socket event fail");
        return false;
    }

    event_add(client_cmd->m_client_socket->m_client_evnt,NULL);

    LOG4CPLUS_DEBUG(logger,"end put client in base");

    event_base_dispatch(m_event_base);

    LOG4CPLUS_DEBUG(logger,"start event base dispatch");
    
    return true;
}

